package pt.isel.pdm.ouryamba;

import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import winterwell.jtwitter.Twitter;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class TimelinePullService extends Service implements Runnable{

	private General app;
	private Thread worker_thread;
	private final String THREAD_NAME = ID + "_worker_thread";
	private final Integer DEFAULT_TOKEN_VALUE = -1;
	public static final String ARG_TOKEN = "onSuccesstoken";
	private final BlockingQueue<Intent> queue = new LinkedBlockingQueue<Intent>();
	public static final String ID = TimelinePullService.class.getName();


//Service methods
	
	/**
	 * Since this is a started service, the is no object to bind.
	 * */
	@Override
	public IBinder onBind(Intent arg0)
	{
		return null;
	}

	/**
	 * Starts the background worker thread and stores a reference for the Application instance. 
	 * */
	@Override
	public void onCreate() 
	{
		worker_thread = new Thread(this, THREAD_NAME);
		worker_thread.start();
		app = (General) getApplication();
		super.onCreate();
	}

	/**
	 * Stops the background worker thread and reference it to null (helps the GC).
	 * */
	@Override
	public void onDestroy()
	{
		worker_thread.interrupt();
		worker_thread = null;
		super.onDestroy();
	}

	/**
	 * Add the new intent to the queue of intents (thread safe).
	 * 
	 * @return The flag START_NOT_STICKY which means the service should not be restarted after
	 * Android killed the service for memory usage.
	 * */
	@Override
	public int onStartCommand(Intent intent, int flags, int startId)
	{
		queue.add(intent);
		return START_NOT_STICKY;
	}
	

//Runnable methods

	/**
	 * Fetches the list of statuses through the worker thread.
	 * 
	 * Fetches one intent from the queues of intents, extracts the token (for further use) and
	 * performs a request through Twitter object to get the user timeline.
	 * That list fetched is then store in the General class.
	 * Later notifies each listener that is "waiting" in the {@code General.toNotifyList} sending
	 * the earlier extracted token.
	 * 
	 * After that the service loops again and fetch another intent from the queue, where the thread
	 * may block and wait if there are none intents.
	 * 
	 * @see General#log(String)
	 * @see General#getTwitter()
	 * @see IMyListener#onSuccess(Integer)
	 * */
	@Override
	public void run() 
	{
		try
		{
			Intent intent;
			Integer token;
			while(true)
			{
				intent = queue.take();
				if(intent == null)
				{
					app.log("TimelinePullService.worker_thread.run(): The intent fetched is null.");
					throw new InterruptedException();
				}
				token = intent.getIntExtra(ARG_TOKEN, DEFAULT_TOKEN_VALUE);
				List<Twitter.Status> list = app.getTwitter().getUserTimeline();
				app.listOfStatuses = list;
				app.log("TimelinePullService.worker_thread.run(): Timeline fetched.");
				if(token != null)
				{
					for(IMyListener waiter : app.toNotifyList)
					{
						app.log("TimelinePullService.worker_thread.run(): Notify IMyListener waiter.");
						waiter.onSuccess(token);
					}
				}
			}
		}
		catch (InterruptedException e)
		{
			app.log("TimelinePullService.worker_thread.run(): Thread interrupted.");
		}
		catch (Exception e)
		{
			app.log("TimelinePullService.worker_thread.run(): Exception thrown.");
			app.log(e.getMessage());
		}
	}

	
}
 